﻿#region 命名空间

using System.Data.Entity;
using System.Reflection;
using System.Threading.Tasks;
using Sharp.Application.Platform;
using Sharp.Domain.PlatformBoundedContext;
using Sharp.Domain.PlatformBoundedContext.ConfigModule;
using Sharp.Domain.PlatformBoundedContext.MasterDataModule.Aggregates;
using Sharp.Domain.PlatformBoundedContext.MasterDataModule.Services;
using Sharp.Domain.PlatformBoundedContext.MessageModule.Aggregates;
using Sharp.Domain.PlatformBoundedContext.MessageModule.Services;
using Sharp.Domain.PlatformBoundedContext.OrgModule.Aggregates;
using Sharp.Domain.PlatformBoundedContext.OrgModule.Services;
using Sharp.Domain.PlatformBoundedContext.PermissionModule.Aggregates;
using Sharp.Domain.PlatformBoundedContext.PersonModule.Aggregates;
using Sharp.Domain.PlatformBoundedContext.PersonModule.Services;
using Sharp.Domain.PlatformBoundedContext.PlatformModule.Aggregates;
using Sharp.Domain.PlatformBoundedContext.UserModule.Aggregates;
using Sharp.Domain.PlatformBoundedContext.WorkFlowModule.Aggregates;
using Sharp.Domain.PlatformBoundedContext.WorkFlowModule.Engine.Business.Manager;
using Sharp.Domain.PlatformBoundedContext.StoragerModule.Aggregates;
using Sharp.Domain.Repositories;
using Sharp.Domain.Repository.EF;
using Sharp.Infrastructure.AutoMapper;
using Sharp.Infrastructure.Crosscutting;
using Sharp.Infrastructure.Interfaces;
using Sharp.Infrastructure.IoC;
using Sharp.ServiceContracts;
using Unity.Interception.ContainerIntegration;
using Unity.Interception.Interceptors.InstanceInterceptors.TransparentProxyInterception;
using Unity.Interception.PolicyInjection;
using Sharp.Domain.PlatformBoundedContext.OAuthModule;
using Sharp.Application.OAuth;

#endregion

namespace Sharp.Services
{
    /// <summary>
    ///     DI container
    /// </summary>
    public class IoCContainer : IBootstrapPlugin
    {
        public IoCContainer()
        {
            Order = int.MaxValue;
        }

        public Assembly[] StartupAssembles { get; set; }
        public int Order { get; set; }
        public void Initialize()
        {
            new AutoMapperInitialize().Initialize(StartupAssembles);

            ServiceLocator.RegisterType<DbContext, Entities>();
            ServiceLocator.RegisterType<IRepositoryContext, EntityFrameworkRepositoryContext>(
               new WcfPerRequestLifetimeManager());

            //Repository
            ServiceLocator.RegisterType<IUserRepository, UserRepository>();
            ServiceLocator.RegisterType<IRoleRepository, RoleRepository>();
            ServiceLocator.RegisterType<IPermissionRepository, PermissionRepository>();
            ServiceLocator.RegisterType<IAvailablePermissionRepository, AvailablePermissionRepository>();
            ServiceLocator.RegisterType<IUserLogRepository, UserLogRepository>();
            ServiceLocator.RegisterType<IResetPasswordRepository, ResetPasswordRepository>();

            ServiceLocator.RegisterType<IGroupRepository, GroupRepository>();
            ServiceLocator.RegisterType<IJobRepository, JobRepository>();
            ServiceLocator.RegisterType<IOrgRepository, OrgRepository>();
            ServiceLocator.RegisterType<IOrgLevelRepository, OrgLevelRepository>();

            ServiceLocator.RegisterType(typeof(IEmployeeRepository), typeof(EmployeeRepository));
            ServiceLocator.RegisterType(typeof(IMasterDataRepository), typeof(MasterDataRepository));
            ServiceLocator.RegisterType(typeof(IMasterDataCategoryRepository), typeof(MasterDataCategoryRepository));

            ServiceLocator.RegisterType<IMessageRepository, MessageRepository>();
            ServiceLocator.RegisterType<INoticeRepository, NoticeRepository>();

            ServiceLocator.RegisterType<ISubSystemRepository, SubSystemRepository>();
            ServiceLocator.RegisterType<IOAuthConfigRepository, OAuthConfigRepository>();
            ServiceLocator.RegisterType<IAuthorizationDataRepository, AuthorizationDataRepository>();

            ServiceLocator.RegisterType<IActivityInstanceEntityRepository, ActivityInstanceEntityRepository>();
            ServiceLocator.RegisterType<ILogEntityRepository, LogEntityRepository>();
            ServiceLocator.RegisterType<IProcessEntityRepository, ProcessEntityRepository>();
            ServiceLocator.RegisterType<IProcessInstanceEntityRepository, ProcessInstanceEntityRepository>();
            ServiceLocator.RegisterType<ITaskEntityRepository, TaskEntityRepository>();
            ServiceLocator.RegisterType<ITransitionInstanceEntityRepository, TransitionInstanceEntityRepository>();


            ServiceLocator.RegisterType<IFileStoreRepository, FileStoreRepository>();

            //// Adapters


            //// Domain Service
            ServiceLocator.RegisterType(typeof(IMasterDataService), typeof(MasterDataService));
            ServiceLocator.RegisterType<IPersonService, PersonService>();
            ServiceLocator.RegisterType<Sharp.Domain.PlatformBoundedContext.UserModule.Services.IUserService, Sharp.Domain.PlatformBoundedContext.UserModule.Services.UserService>();
            ServiceLocator.RegisterType<IOrgService, OrgService>();
            ServiceLocator.RegisterType<IMessageService, MessageService>();

            ServiceLocator.RegisterType<IActivityInstanceManager, ActivityInstanceManager>();
            ServiceLocator.RegisterType<ILogManager, LogManager>();
            ServiceLocator.RegisterType<IProcessInstanceManager, ProcessInstanceManager>();
            ServiceLocator.RegisterType<IProcessManager, ProcessManager>();
            ServiceLocator.RegisterType<ITaskManager, TaskManager>();
            ServiceLocator.RegisterType<ITransitionInstanceManager, TransitionInstanceManager>();


            //// Application Service Implementations
            ServiceLocator.RegisterType<IEnterpriseService, EnterpriseServiceImp>(
                new Interceptor<TransparentProxyInterceptor>(),
                new InterceptionBehavior<PolicyInjectionBehavior>(),
                new InterceptionBehavior(new ExceptionLoggingBehavior()));

            ServiceLocator.RegisterType<IUserService, UserServiceImpl>(
                new Interceptor<TransparentProxyInterceptor>(),
                new InterceptionBehavior<PolicyInjectionBehavior>(),
                new InterceptionBehavior(new ExceptionLoggingBehavior()));

            ServiceLocator.RegisterType(typeof(IPlatformService), typeof(PlatformServiceImpl),
                new Interceptor<TransparentProxyInterceptor>(),
                new InterceptionBehavior<PolicyInjectionBehavior>(),
                new InterceptionBehavior(new ExceptionLoggingBehavior())
                );

            ServiceLocator.RegisterType(typeof(IWorkflowService), typeof(WorkflowServiceImpl),
                new Interceptor<TransparentProxyInterceptor>(),
                new InterceptionBehavior<PolicyInjectionBehavior>(),
                new InterceptionBehavior(new ExceptionLoggingBehavior())
                );
            ServiceLocator.RegisterType(typeof(IOAuthService), typeof(OAuthServiceImpl),
                new Interceptor<TransparentProxyInterceptor>(),
                new InterceptionBehavior<PolicyInjectionBehavior>(),
                new InterceptionBehavior(new ExceptionLoggingBehavior())
                );


            //ServiceLocator.RegisterType<IBootstrapPlugin, Sharp.Application.Platform.Bootstraper>("A");
            //ServiceLocator.RegisterType<IBootstrapPlugin, Sharp.Domain.PlatformBoundedContext.Bootstraper>("B");
        }

        public Task InitializeAsync()
        {
            return Task.FromResult(0);
        }

        public bool IsAlready { get; set; }
    }
}